import { router_metadata } from "../constant";
import { RequestMethod } from "../enum";
import { RequestMethodType, RouteData } from "./types";

const RequestMapping = (method: RequestMethodType) => {
  return (path: string): MethodDecorator => {
    return (target: any, key: string | symbol, descriptor: TypedPropertyDescriptor<any>) => {
      let routerData: RouteData[] = [];
      if (Reflect.hasOwnMetadata(router_metadata, target.constructor)) {
        routerData = Reflect.getMetadata(router_metadata, target.constructor);
      }
      routerData.push({
        path: path,
        requestMethod: method,
        method: descriptor.value,
        methodName: key,
        target: target.constructor,
        name: target.constructor.name,
      });
      Reflect.defineMetadata(router_metadata, routerData, target.constructor);
      return descriptor;
    };
  };
};

export const Get = RequestMapping(RequestMethod.GET);
export const Post = RequestMapping(RequestMethod.POST);
export const Put = RequestMapping(RequestMethod.PUT);
export const Delete = RequestMapping(RequestMethod.DELETE);
export const Patch = RequestMapping(RequestMethod.PATCH);
export const Options = RequestMapping(RequestMethod.OPTIONS);
export const Head = RequestMapping(RequestMethod.HEAD);
export const All = RequestMapping(RequestMethod.ALL);
